package com.heima.user.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.common.constants.message.FollowBehaviorConstants;
import com.heima.common.exception.CustException;
import com.heima.feigns.article.ArticleFeign;
import com.heima.model.article.pojos.ApAuthor;
import com.heima.model.behavior.dtos.FollowBehaviorDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.dtos.UserRelationDto;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.user.pojos.ApUserFan;
import com.heima.model.user.pojos.ApUserFollow;
import com.heima.user.mapper.ApUserFanMapper;
import com.heima.user.mapper.ApUserFollowMapper;
import com.heima.user.mapper.ApUserMapper;
import com.heima.user.service.UserRelationService;
import com.heima.utils.threadlocal.AppThreadLocalUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
@Service
public class UserRelationServiceImpl implements UserRelationService {
    @Autowired
    ArticleFeign articleFeign;
    @Autowired
    ApUserFollowMapper apUserFollowMapper;
    @Autowired
    ApUserFanMapper apUserFanMapper;
    /**
     * 用户关注/取消关注
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult follow(UserRelationDto dto) {
        /*1参数检查*/
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        if (dto.getOperation() == null || dto.getOperation() < 0 || dto.getOperation() > 1) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        if (dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        /*2获取作者*/
        ApAuthor apAuthor = articleFeign.selectById(dto.getAuthorId());
        if (apAuthor == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "关注用户不存在");
        }
        /*3判断是否登录*/
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN, "需要登陆后查看");
        }
        /*4关注：执行保存ap_user_follow和ap_user_fans信息
         * 取消关注：则删除两张表信息
         * */
        if (dto.getOperation() == 0) {
            return followByUserId(user.getId(),apAuthor.getUserId(),dto.getArticleId());
        } else {
            return followCancelByUserId(user.getId(),apAuthor.getUserId());
        }
    }

    /**
     * 关注
     *
     * @param userId   普通用户（当前登录人）
     * @param followUserId 被关注的作者对应的apUser id
     * @param /articleId 文章id
     * @return
     */
    @Autowired
    ApUserMapper apUserMapper;
    @Autowired
    KafkaTemplate kafkaTemplate;
    private ResponseResult followByUserId(Integer userId,Integer followUserId,Long articleId) {
        /*1参数检查*/
        if (userId == null || followUserId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
            /*获取被关注作者对应的apuser*/
        ApUser followUser = apUserMapper.selectById(followUserId);
        if (followUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "关注用户不存在");
        }
        if (userId.intValue() == followUser.getId().intValue()) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_EXIST, "不能关注自己");

        }
        /*2保存用户的关注信息*/
            /*判断ap_user_follow表是否存在*/
        ApUserFollow apUserFollow = apUserFollowMapper.selectOne(Wrappers.<ApUserFollow>lambdaQuery().eq(ApUserFollow::getUserId, userId).eq(ApUserFollow::getFollowId, followUser.getId()));
        if (apUserFollow != null) {
            CustException.cust(AppHttpCodeEnum.DATA_EXIST);
        }
            /*（不存在）创建新的ap_user_follow对象，并插入*/
        apUserFollow = new ApUserFollow();
        apUserFollow.setFollowId(followUserId);
        apUserFollow.setUserId(userId);
        apUserFollow.setLevel((short)1);
        apUserFollow.setIsNotice(true);
        apUserFollow.setFollowName(followUser.getName());
        apUserFollow.setCreatedTime(new Date());
        apUserFollowMapper.insert(apUserFollow);
        /*3保存作者的粉丝信息*/
        ApUserFan apUserFan = apUserFanMapper.selectOne(Wrappers.<ApUserFan>lambdaQuery()
                .eq(ApUserFan::getFansId, userId).eq(ApUserFan::getUserId, followUserId));
        if (apUserFan != null) {
            CustException.cust(AppHttpCodeEnum.DATA_EXIST);
        }
        apUserFan = new ApUserFan();
        apUserFan.setUserId(followUserId);
        apUserFan.setCreatedTime(new Date());
        apUserFan.setLevel((short)0);
        apUserFan.setIsShieldComment(false);
        apUserFan.setIsShieldLetter(false);
        apUserFan.setIsDisplay(true);
        apUserFan.setFansId(userId.longValue());
        // 粉丝名称
        ApUser apUser = apUserMapper.selectById(userId);
        apUserFan.setFansName(apUser.getName());

        apUserFanMapper.insert(apUserFan);
        //4 记录用户的关注行为
        FollowBehaviorDto followBehaviorDto = new FollowBehaviorDto();
        followBehaviorDto.setUserId(apUser.getId());
        followBehaviorDto.setFollowId(followUser.getId());
        followBehaviorDto.setArticleId(articleId);
        /*kafka异步发送消息，保存关注行为*/
        kafkaTemplate.send(FollowBehaviorConstants.FOLLOW_BEHAVIOR_TOPIC, JSON.toJSONString(followBehaviorDto));

        // 返回结果
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
    /**
     * 取消关注
     * @param userId   普通用户（当前登录人）
     * @param followUserId 被关注的作者对应的apUser id
     * @return
     */
    private ResponseResult followCancelByUserId(Integer userId, Integer followUserId) {

        // 删除当前用户关注信息
        apUserFollowMapper.delete(Wrappers.<ApUserFollow>lambdaQuery()
                .eq(ApUserFollow::getFollowId, followUserId)
                .eq(ApUserFollow::getUserId, userId));

        // 删除被关注的粉丝信息
        apUserFanMapper.delete(Wrappers.<ApUserFan>lambdaQuery()
                .eq(ApUserFan::getFansId, userId)
                .eq(ApUserFan::getUserId, followUserId));

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

}

